package com.yc.mybatis.core;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.yc.mybatis.bean.GoodsInfo;
import com.yc.mybatis.bean.GoodsType;

public class SqlSession {
	private ConnectionPool connectionPool;
	private Map<String,MapperInfo> mapperInfos;

	public SqlSession(ConnectionPool connectionPool, Map<String, MapperInfo> mapperInfos) {
		this.connectionPool = connectionPool;
		this.mapperInfos = mapperInfos;
	}
    @SuppressWarnings("unchecked")
	public <T> T selectOne(String sqlId, Object obj) {
    	if(mapperInfos == null || mapperInfos.isEmpty()) {
			throw new RuntimeException("没有读取到映射文件信息。。。。。");
		}
		
		MapperInfo mapperInfo = mapperInfos.getOrDefault(sqlId, null);
		if(mapperInfo == null) {
			throw new RuntimeException("找不到您要执行的"+sqlId +"...");
		}
		Connection con =null;
		
		try {
			con = connectionPool.getConnection();//从连接池中获得一个可用的连接
			String sql = mapperInfo.getSql();//获得执行语句
			List<String> params = mapperInfo.getParams();
			List<Object> parmasValue = null; //占位符的值
			if(params!= null && !params.isEmpty()) { //说明sql语句中有占位符
				parmasValue = this.getParamsValue(params, mapperInfo.getParameterType(), obj);	
			}
			
			DBUtil db = new DBUtil();
			String resultType = mapperInfo.getResultType();
			if("int".equalsIgnoreCase(resultType)) {
				return (T) db.total(con, sql, parmasValue);
			}
			if("map".equalsIgnoreCase(resultType)) {
				return (T) db.findOne(con,sql,parmasValue);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public <T>List<T> selectList(String sqlId) {
		return this.selectList(sqlId,null);
	}
	
	@SuppressWarnings("unchecked")
	public <T>List<T> selectList(String sqlId,Object obj) {
		if(mapperInfos == null || mapperInfos.isEmpty()) {
			throw new RuntimeException("没有读取到映射文件信息.......");
		}
		
		MapperInfo mapperInfo = mapperInfos.getOrDefault(sqlId, null);
		if(mapperInfo == null) {
			throw new RuntimeException("找不到您要执行的"+sqlId +"...");
		}
		
		Connection con = null;
		try {
			
			con = connectionPool.getConnection(); //从连接池中获取一个可用的连接
			String sql = mapperInfo.getSql(); //获取要执行的sql语句
			List<String> params = mapperInfo.getParams();//获取指定语句在的占位符
			List<Object> paramsValue = null;  //存在每一个占位符的值
			
			if(params != null && !params.isEmpty()) {//说明sql语句中有占位符，此时需要从用户给定的对象中，按顺序取出占位符的值
				paramsValue = getParamsValue(params,mapperInfo.getParameterType(),obj);
			}
			
			DBUtil db = new DBUtil();
			String resultType = mapperInfo.getResultType();
			if("map".equalsIgnoreCase(resultType)) {
				return (List<T>)db.findList(con, sql,paramsValue);
			}
			Class<?> clazz = Class.forName(resultType);
			return db.findList(con,clazz,sql, paramsValue);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(con != null) {
				this.close(con);
			}
		}
		
		
		return null;
	}

	public int insert(String string, Object obj) {
		return 0;
	}

	public int insert(String string) {
		return 0;
	}

	public int update(String sqlId,Object obj) {
		if(mapperInfos == null || mapperInfos.isEmpty()) {
			throw new RuntimeException("没有读取到映射文件信息.......");
		}
		
		MapperInfo mapperInfo = mapperInfos.getOrDefault(sqlId, null);
		if(mapperInfo == null) {
			throw new RuntimeException("找不到您要执行的"+sqlId +"...");
		}
		
		int result = -1;
		Connection con = null;
		
		try {
			con = connectionPool.getConnection(); //从连接池中获取一个可用的连接
			String sql = mapperInfo.getSql(); //获取要执行的sql语句
			List<String> params = mapperInfo.getParams();//获取指定语句在的占位符
			List<Object> paramsValue = null;  //存在每一个占位符的值
			
			if(params != null && !params.isEmpty()) {//说明sql语句中有占位符，此时需要从用户给定的对象中，按顺序取出占位符的值
				paramsValue = getParamsValue(params,mapperInfo.getParameterType(),obj);
			}
			
			DBUtil db = new DBUtil();
			result = db.update(con,sql,paramsValue);
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(con != null) {
				this.close(con);
			}
		}
		return result;
	}
	/**
	 * 释放连接给连接池的方法
	 * @param con
	 */
	private void close(Connection con) {
		connectionPool.freeConnection(con);
		
	}
/**
 * 根据用户指定的参数类型从用户给定的对象中取出占位符的值
 * @param params
 * @param parameterType
 * @param obj
 * @return
 * @throws Exception 
 */
	private List<Object> getParamsValue(List<String> params, String parameterType, Object obj) throws Exception {
		if(params == null || params.isEmpty() || obj == null || StringUtil.checkNull(parameterType)) {
			return Collections.emptyList();
		}
		
		List<Object> vals = new ArrayList<Object>();
		
		if("int".equalsIgnoreCase(parameterType) || "float".equalsIgnoreCase(parameterType) 
				|| "double".equalsIgnoreCase(parameterType) || "string".equalsIgnoreCase(parameterType)) {
			vals.add(obj);
			return vals;
		}
		
		if("map".equalsIgnoreCase(parameterType)) {
			Map<String,Object> map = (Map<String, Object>) obj;
			for(String key : params) {
				vals.add(map.get(key));
			}
			return vals;
		}
		
		//用户自定义的对象
		Class<?> clazz = Class.forName(parameterType);
		
		//获得这个类中的getter方法 -》 获得这个类的所以方法
		Method[] methods = clazz.getDeclaredMethods();
		if(methods == null && methods.length <=0) {
			return vals;
		}
		
		
		//从这个方法中找出getter
		Map<String,Method> getters = new HashMap<String,Method>();
		String methodName =null;
		for(Method method : methods) {//遍历所以方法
			methodName = method.getName();
			if(methodName.startsWith("get")) {
				getters.put(methodName, method);
			}
			
		}
		
		Method method = null;
		for(String attrName : params) {
			methodName = "get" + attrName.substring(0,1).toUpperCase() + attrName.substring(1);
			
			//判断这个属性的getter方法是否存在
			method = getters.get(methodName);
			if(method == null) { //说明这个属性没有提供对应的getter方法
				vals.add(null); //那么这个属性的值就没法注入，则说明该属性的值为空
				continue;
			}
			
			//如果有这个方法，则需要激活运行这个方法
			//obj.getGname()
			vals.add(method.invoke(obj));
		}
		return vals;
	}

	public int update(String string) {
		return 0;
	}
	
	public int delete(String string,Object obj) {
		return 0;
	}
	
	public int delete(String string) {
		return 0;
	}
}
